/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package com.chagee.store.operation.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.chagee.base.utils.PaginationRequest;
import com.chagee.store.operation.common.constant.CommonConstant;
import com.chagee.store.operation.common.exception.BizErrorCode;
import com.chagee.store.operation.common.exception.BizException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.HibernateValidator;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.io.Serializable;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 通用工具类
 *
 * @author Chill
 */

@Slf4j
public class CommonUtil {
	private static final Validator validator = Validation.byProvider(HibernateValidator.class)
		.configure()
		.failFast(false)
		.buildValidatorFactory()
		.getValidator();


	private static final String EXPORT_FILE_NAME_DATE_FOMAT = "yyyy-MM-dd HH-mm-ss";
	private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

	/**
	 * check param
	 *
	 * @param param
	 * @return
	 */
	public static String validate(Object param) {
		Set<ConstraintViolation<Object>> validate = validator.validate(param);
		if (!CollectionUtils.isEmpty(validate)) {
			return validate.stream().findFirst().get().getMessage();
		}
		return null;
	}

	/**
	 * check param
	 *
	 * @param param
	 * @return
	 */
	public static String validateAndWarn(Object param) {
		Set<ConstraintViolation<Object>> validate = validator.validate(param);
		if (!CollectionUtils.isEmpty(validate)) {
			return validate.stream().map(ConstraintViolation::getMessage).filter(StringUtils::isNotBlank).collect(Collectors.joining(CommonConstant.OR_STRING));
		}
		return StringUtils.EMPTY;
	}


	/**
	 * check param
	 *
	 * @param param
	 * @return
	 */
	public static void validateOrThrow(Object param) {
		if (Objects.isNull(param)) {
			throw new BizException(BizErrorCode.PARAMETER_IS_NULL);
		}
		Set<ConstraintViolation<Object>> validate = validator.validate(param);
		if (!CollectionUtils.isEmpty(validate)) {
			Optional<ConstraintViolation<Object>> first = validate.stream().findFirst();
			if (first.isPresent()) {
				throw new BizException(BizErrorCode.REQUEST_VALID_FAILED, first.get().getMessage());
			}
		}
	}


	@SneakyThrows
	public static void downloadResponse(HttpServletResponse response, String fileNamePrefix) {
		response.setContentType("application/octet-stream");
		response.setCharacterEncoding("UTF-8");
		String fileName = fileNamePrefix + "_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern(EXPORT_FILE_NAME_DATE_FOMAT)) + ".xlsx";
		String fileNameEncode = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
		response.setHeader("Content-disposition", "attachment;filename=" + fileNameEncode);
		response.setHeader("FileName", fileNameEncode);

	}

	@SneakyThrows
	public static void download(HttpServletResponse response, String fileNamePrefix) {
		response.setContentType("application/octet-stream");
		response.setCharacterEncoding("UTF-8");
		String fileName = fileNamePrefix + "_" + DATE_TIME_FORMAT.format(LocalDateTime.now()) + ".xlsx";
		String fileNameEncode = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
		response.setHeader("Content-disposition", "attachment;filename=" + fileNameEncode);
		response.setHeader("FileName", fileNameEncode);

	}

	@SneakyThrows
	public static String encodeChineseCharacters(String url) {
		StringBuilder sb = new StringBuilder();
		for (char c : url.toCharArray()) {
			if ((c >= '\u4e00' && c <= '\u9fa5') || Character.isWhitespace(c)) { // 判断是否是中文字符
				sb.append(java.net.URLEncoder.encode(String.valueOf(c), "UTF-8"));
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	public static String getRedisKey(String... keys) {
		if (keys.length == 0) {
			return StringUtils.EMPTY;
		}
		StringBuilder stringBuilder = new StringBuilder();
		for (String key : keys) {
			stringBuilder.append(key).append(":");
		}
		return stringBuilder.substring(0, stringBuilder.length() - 1);
	}


	public static <T extends Serializable> PaginationRequest<T> convertPageRequest(T queryParam, int pageNum, int pageSize){
		PaginationRequest<T> request = new PaginationRequest<>();
		request.setQueryParameter(queryParam);
		request.setPageNum(pageNum);
		request.setPageSize(pageSize);
		return request;
	}

	public static <T extends Serializable> PaginationRequest<T> convertPageRequest(T queryParam, PaginationRequest<T> pagRequest){
		PaginationRequest<T> request = new PaginationRequest<>();
		request.setQueryParameter(queryParam);
		request.setPageNum(pagRequest.getPageNum());
		request.setPageSize(pagRequest.getPageSize());
		return request;
	}

}
